package cn.middle.remote.exchange;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;


public abstract class AbstractSignalFuture implements SignalFuture {

	protected static Map<String, AbstractSignalFuture> FUTURES = new ConcurrentHashMap<>();

	protected int timeout;
	
	protected AbstractSignalFuture(String msgId) {
		FUTURES.put(msgId, this);
	}

	/**
	 * 默认3秒超时
	 */
	protected static final int DEFAULT_TIME_OUT = 30000;
	
	/**
	 * 回调生成时间
	 */
	protected long generatedstamp = System.currentTimeMillis();	
	
	public static void callResponse(String msgId,byte[] data) {
		AbstractSignalFuture future = FUTURES.remove(msgId);
		if(future != null) {
			future.doResponse(data);
		}
	}
	
	public static void setCause(String msgId,Throwable cause) {
		AbstractSignalFuture future = FUTURES.remove(msgId);
		if(future != null) {
			future.cause(cause);
		}
	}
	
	
	public abstract void doResponse(byte[] data);
	
	public abstract void cause(Throwable cause);
	
	static {
		//启动检测线程，移除超时的future 
		Thread t = new Thread(new TimeOutFutureHandler());
		t.setName("timeoutFutureHandler");
		t.setDaemon(true);//后台线程
		t.start();
	}
	
	private static class TimeOutFutureHandler implements Runnable {

		@Override
		public void run() {
			for(;;) {
				long startStamp = System.currentTimeMillis(); //当前时间戳
			
				Set<String> allKeys =  FUTURES.keySet();
				Set<String> removeKeys = new HashSet<>(); //移除future key集
				
				for(String key : allKeys) {
					AbstractSignalFuture future = FUTURES.get(key);
					int timeout = future.timeout <= 0 ? DEFAULT_TIME_OUT : future.timeout; //获取超时间隔
					long futureStamp = future.generatedstamp;// future 创建的时间戳
					if((startStamp - futureStamp) >= timeout) {  //超过时间future key 放入移除集合中，等待移除
						removeKeys.add(key);
					}
				}
				
				//移除超时key 
				for(String removeKey :removeKeys) {
					FUTURES.remove(removeKey);
				}
				
				try {
					Thread.sleep(60); //体眠60 毫秒，防止循环过快导致占用CPU过高！
				} catch (InterruptedException e) {
			
				}
			}
		}
	}

}
